package com.nine.demo.controller;

import com.nine.demo.dto.UserInfoDto;
import com.nine.demo.entity.UserInfo;
import com.nine.demo.properties.MinioProperties;
import com.nine.demo.result.R;
import com.nine.demo.service.UserContractService;
import com.nine.demo.service.UserImageService;
import com.nine.demo.service.UserInfoService;
import io.minio.GetObjectArgs;
import io.minio.GetObjectResponse;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.net.URLEncoder;
import java.util.List;

/**
 * @author nine
 * @version 1.0
 * @description TODO
 * @date 2024-08-05 23:17
 */
@RestController
@RequestMapping
@CrossOrigin
@Slf4j
public class UserInfoController {

	@Autowired
	private UserInfoService userInfoService;

	@Autowired
	private MinioProperties minioProperties;

	@Autowired
	private MinioClient minioClient;

	@Autowired
	private UserImageService userImageService;

	@Autowired
	private UserContractService userContractService;

	/**
	 * 获取列表
	 *
	 * @return
	 */
	@GetMapping("/api/user")
	public R userList() {
		List<UserInfo> list = userInfoService.list();
		return R.ok(list);
	}

	/**
	 * 获取详情
	 *
	 * @param id
	 * @return
	 */
	@GetMapping("/api/user/{id}")
	public R userInfo(@PathVariable("id") Integer id) {
		UserInfo userInfo = userInfoService.getUserById(id);
		return R.ok(userInfo);
	}

	/**
	 * 上传图片
	 *
	 * @param file
	 * @return
	 */
	@PostMapping("/api/user/image")
	public R image(MultipartFile file, @RequestParam("id") Integer id) {
		String bucketName = minioProperties.getBucketName();
		try {
			minioClient.putObject(PutObjectArgs.builder().bucket(bucketName)
					// 文件名称
					.object(file.getOriginalFilename())
					// 文件传递
					.stream(file.getInputStream(), file.getSize(), -1).build());

			// 插入或更新
			boolean flag = userImageService.saveorUpdateImage(id, bucketName, file.getOriginalFilename());
			if (flag) {
				log.info("文件上传成功：" + id);
			}
		}
		catch (Exception e) {
			throw new RuntimeException(e);
		}

		return R.ok();
	}

	/**
	 * 上传文件
	 *
	 * @param file
	 */
	@PostMapping("/api/user/contract")
	public R contract(MultipartFile file, @RequestParam("id") Integer id) {
		String bucketName = minioProperties.getBucketName();
		try {
			minioClient.putObject(PutObjectArgs.builder().bucket(bucketName)
					// 文件名称
					.object(file.getOriginalFilename())
					// 文件传递
					.stream(file.getInputStream(), file.getSize(), -1).build());
			// 插入或更新
			boolean flag = userContractService.saveorUpdateContract(id, bucketName, file.getOriginalFilename());
			if (flag) {
				log.info("文件上传成功：" + id);
			}
		}
		catch (Exception e) {
			throw new RuntimeException(e);
		}
		return R.ok();
	}

	/**
	 * 修改【没有添加 @ResponseBody 注解，前端需要使用 formData 提交】
	 *
	 * @param userInfoDto
	 * @return
	 */
	@PostMapping("/api/user")
	public R updateUser(UserInfoDto userInfoDto) {
		UserInfo userInfo = userInfoDto.convert();
		boolean save = userInfoService.updateById(userInfo);
		return save ? R.ok() : R.error();
	}

	@GetMapping("/api/user/download/{id}")
	public void download(@PathVariable("id") Integer id, HttpServletResponse response) {
		UserInfo userInfo = userInfoService.getUserById(id);
		String fileName = userInfo.getUserContract().getObject();

		// 设置响应头
		try {
			response.setCharacterEncoding("utf-8");
			response.setContentType("application/octet-stream");
			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));

			GetObjectResponse clientObject = minioClient.getObject(GetObjectArgs.builder().bucket(minioProperties.getBucketName()).object(fileName).build());
			clientObject.transferTo(response.getOutputStream());
		}
		catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

}
